package com.ruoyi.system.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.system.domain.Department;
import com.ruoyi.system.domain.Doctor;
import com.ruoyi.system.domain.vo.DoctorScheduleVO;
import com.ruoyi.system.domain.vo.PageResult;
import com.ruoyi.system.domain.vo.Result;
import com.ruoyi.system.mapper.DepartmentMapper;
import com.ruoyi.system.mapper.DoctorMapper;
import com.ruoyi.system.mapper.DoctorScheduleMapper;
import com.ruoyi.system.service.IDoctorScheduleService;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

/**
 * 医生排班Service业务层处理
 *
 * @author ruoyi
 * @date 2025-05-09
 */
@Service
public class DoctorScheduleServiceImpl implements IDoctorScheduleService {
    @Autowired
    private DoctorScheduleMapper doctorScheduleMapper;
    // 医生
    @Autowired
    private DoctorMapper doctorMapper;
    // 科室
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private RedisService redisService;

    // Redis缓存key前缀
    private static final String CACHE_KEY_SCHEDULE = "doctor:schedule:";
    private static final String CACHE_KEY_SCHEDULE_WEEK = "doctor:schedule:week:";
    private static final long CACHE_EXPIRE = 30; // 缓存过期时间（分钟）

    /**
     * 根据条件分页查询医生排班信息
     */
    @Override
    public PageResult selectDoctorScheduleByWeek(int pageNum, int pageSize, Integer departmentId, String patientName, String weekStart, String weekEnd) {
        String cacheKey = CACHE_KEY_SCHEDULE_WEEK + weekStart + ":" + weekEnd + ":" + departmentId + ":" + patientName + ":" + pageNum + ":" + pageSize;
        
        // 尝试从缓存获取数据
        PageResult cachedResult = redisService.getCacheObject(cacheKey);
        if (cachedResult != null) {
            return cachedResult;
        }

        // 缓存未命中，执行数据库查询
        PageHelper.startPage(pageNum, pageSize);
        List<DoctorScheduleVO> list = doctorScheduleMapper.selectDoctorScheduleByWeek(departmentId, patientName, weekStart, weekEnd);
        
        for (DoctorScheduleVO doctorScheduleVO : list) {
            // 医生信息
            Doctor doctor = doctorMapper.selectDoctorById(doctorScheduleVO.getDoctorId());
            doctorScheduleVO.setDoctorName(doctor.getName());
            // 科室信息
            doctorScheduleVO.setDepartmentName(departmentMapper.selectById(doctor.getDepartmentId()));
            if (doctorScheduleVO.getPatientId() != null) {
                // 就诊人信息
                doctorScheduleVO.setPatientName(doctorMapper.selectDoctorByIdName(Long.valueOf(doctorScheduleVO.getPatientId())));
            }
        }

        PageInfo<DoctorScheduleVO> pageInfo = new PageInfo<>(list);
        PageResult result = new PageResult(pageInfo.getTotal(), pageInfo.getList());
        
        // 将结果存入缓存
        redisService.setCacheObject(cacheKey, result, CACHE_EXPIRE, TimeUnit.MINUTES);
        
        return result;
    }

    /**
     * 根据ID查询医生排班信息
     */
    @Override
    public Result selectDoctorScheduleById(Long id) {
        String cacheKey = CACHE_KEY_SCHEDULE + id;
        
        // 尝试从缓存获取数据
        DoctorScheduleVO cachedSchedule = redisService.getCacheObject(cacheKey);
        if (cachedSchedule != null) {
            return Result.success(200, "查询成功", cachedSchedule);
        }

        try {
            DoctorScheduleVO doctorScheduleVO = doctorScheduleMapper.selectDoctorScheduleById(id);
            if (doctorScheduleVO != null) {
                // 将结果存入缓存
                redisService.setCacheObject(cacheKey, doctorScheduleVO, CACHE_EXPIRE, TimeUnit.MINUTES);
            }
            return Result.success(200, "查询成功", doctorScheduleVO);
        } catch (Exception e) {
            return Result.error(500, "查询医生排班信息失败");
        }
    }

    /**
     * 新增医生排班信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result insertDoctorSchedule(DoctorScheduleVO doctorScheduleVO) {
        try {
            int rows = doctorScheduleMapper.insertDoctorSchedule(doctorScheduleVO);
            if (rows > 0) {
                // 清除相关缓存
                clearScheduleCache(doctorScheduleVO);
                return Result.success(200, "新增成功", null);
            }
            return Result.error(500, "新增失败");
        } catch (Exception e) {
            return Result.error(500, "新增医生排班信息失败");
        }
    }

    /**
     * 修改医生排班信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateDoctorSchedule(DoctorScheduleVO doctorScheduleVO) {
        try {
            int rows = doctorScheduleMapper.updateDoctorSchedule(doctorScheduleVO);
            if (rows > 0) {
                // 清除相关缓存
                clearScheduleCache(doctorScheduleVO);
                return Result.success(200, "修改成功", null);
            }
            return Result.error(500, "修改失败");
        } catch (Exception e) {
            return Result.error(500, "修改医生排班信息失败");
        }
    }

    /**
     * 删除医生排班信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteDoctorScheduleById(Long id) {
        try {
            // 先获取排班信息，用于后续清除缓存
            DoctorScheduleVO schedule = doctorScheduleMapper.selectDoctorScheduleById(id);
            int rows = doctorScheduleMapper.deleteDoctorScheduleById(id);
            if (rows > 0) {
                // 清除相关缓存
                if (schedule != null) {
                    clearScheduleCache(schedule);
                }
                return Result.success(200, "删除成功", null);
            }
            return Result.error(500, "删除失败");
        } catch (Exception e) {
            return Result.error(500, "删除医生排班信息失败");
        }
    }

    /**
     * 获取医生排班详情
     */
    @Override
    public Result getDoctorScheduleDetail(Long doctorId, String date, String period) {
        String cacheKey = CACHE_KEY_SCHEDULE + doctorId + ":" + date + ":" + period;
        
        // 尝试从缓存获取数据
        DoctorScheduleVO cachedDetail = redisService.getCacheObject(cacheKey);
        if (cachedDetail != null) {
            return Result.success(200, "查询成功", cachedDetail);
        }

        try {
            DoctorScheduleVO detail = doctorScheduleMapper.getDoctorScheduleDetail(doctorId, date, period);
            if (detail != null) {
                // 将结果存入缓存
                redisService.setCacheObject(cacheKey, detail, CACHE_EXPIRE, TimeUnit.MINUTES);
            }
            return Result.success(200, "查询成功", detail);
        } catch (Exception e) {
            return Result.error(500, "查询排班详情失败");
        }
    }

    /**
     * 获取所有科室列表
     */
    @Override
    public Result getDepartmentList() {
        try {
            List<Department> list = doctorScheduleMapper.selectAll();
            return Result.success(200, "查询成功", list);
        } catch (Exception e) {
            return Result.error(500, "获取科室列表失败");
        }
    }

    /**
     * 清除排班相关的缓存
     */
    private void clearScheduleCache(DoctorScheduleVO schedule) {
        if (schedule == null) {
            return;
        }
        // 清除详情缓存
        String detailKey = CACHE_KEY_SCHEDULE + schedule.getId();
        redisService.deleteObject(detailKey);
        
        // 清除周排班缓存（使用模糊匹配删除）
        String weekPattern = CACHE_KEY_SCHEDULE_WEEK + "*";
        redisService.deleteObject(weekPattern);
        
        // 清除排班详情缓存
        if (schedule.getDoctorId() != null && schedule.getScheduleDate() != null) {
            String morningKey = CACHE_KEY_SCHEDULE + schedule.getDoctorId() + ":" + schedule.getScheduleDate() + ":上午";
            String afternoonKey = CACHE_KEY_SCHEDULE + schedule.getDoctorId() + ":" + schedule.getScheduleDate() + ":下午";
            redisService.deleteObject(morningKey);
            redisService.deleteObject(afternoonKey);
        }
    }
}
